package hibernatemock;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToOne;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

public class AnnotationHandler {

	public boolean isRequired(Field field) {

		if (fieldOrGetterHasAnnotation(field, NotNull.class) != null || fieldOrGetterHasAnnotation(field, Size.class) != null)
			return true;

		Column column = (Column) fieldOrGetterHasAnnotation(field, Column.class);
		if (column != null && column.nullable() == false)
			return true;

		JoinColumn joinColumn = (JoinColumn) fieldOrGetterHasAnnotation(field, JoinColumn.class);
		if (joinColumn != null && joinColumn.nullable() == false)
			return true;

		Basic basic = (Basic) fieldOrGetterHasAnnotation(field, Basic.class);
		if (basic != null && basic.optional() == false)
			return true;

		OneToOne oneToOne = (OneToOne) fieldOrGetterHasAnnotation(field, OneToOne.class);
		if (oneToOne != null && oneToOne.optional() == false)
			return true;

		ManyToOne manyToOne = (ManyToOne) fieldOrGetterHasAnnotation(field, ManyToOne.class);
		if (manyToOne != null && manyToOne.optional() == false)
			return true;
		
		//if (!field.getClass().isAnnotationPresent(Entity.class))
			//return true;

		return false;
	}

	public Annotation fieldOrGetterHasAnnotation(Field field, Class<? extends Annotation> annotation) {
		if (field.isAnnotationPresent(annotation)) {
			for (Annotation annotation2 : field.getDeclaredAnnotations()) {
				if (annotation == annotation2.annotationType())
					return annotation2;
			}
		}
		try {
			String getterName = "get" + field.getName().substring(0, 1).toUpperCase() + field.getName().substring(1);
			Class<?>[] parameter = null;
			Method method = field.getDeclaringClass().getMethod(getterName, parameter);
			if (method.isAnnotationPresent(annotation)) {
				for (Annotation annotation2 : method.getDeclaredAnnotations()) {
					if (annotation == annotation2.annotationType())
						return annotation2;
				}
			}
		} catch (Exception e) {
			return null;
		}
		return null;
	}

}
